{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "name": "189_HW6_Q4_A_F.ipynb",
      "provenance": [],
      "collapsed_sections": [
        "Dl8GOKOqiIDN",
        "kJQ-2_RbW8I6",
        "t0cogbZJW_RY",
        "vTgDUCyniIDh",
        "Ap4zZNDjiIDo"
      ]
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.6.8"
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "accelerator": "GPU"
  },
  "cells": [
    {
      "cell_type": "code",
      "metadata": {
        "id": "nd8iaSjXiICq",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "%load_ext autoreload\n",
        "%autoreload 2"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "TosggIXPCqDI",
        "colab": {}
      },
      "source": [
        "import os, sys\n",
        "from google.colab import drive\n",
        "drive.mount('/gdrive')\n",
        "sys.path.insert(0, \"/content/gdrive/My Drive/CS 189/hw/hw6-collabtry/\")\n",
        "%cd /gdrive/My\\ Drive/CS\\ 189/hw/hw6-collabtry/"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "aSE2LyHNIN2K",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "import numpy as np\n",
        "from torchsummary import summary\n",
        "import pandas as pd\n",
        "from sklearn.metrics import confusion_matrix\n",
        "import pickle\n",
        "import torch"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "t0WRrf1_iICw",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "!pip install torchsummary"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "ormkojCMiIC7",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "np.random.seed(10)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "zzYBme3CiIDA",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "models_data = []"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "S5Hf7oFCiIDE",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "def plot_loss(arch,train,val):\n",
        "    mt = sum(train)/len(train)\n",
        "    mv = sum(val)/len(val)\n",
        "    plt.title(arch+\", Avg Train Loss: \"+str(round(mt,4))+\", Avg Val Loss: \"+str(round(mv,4)))\n",
        "    plt.plot([i+1 for i in range(len(train))], train, 'r', label=\"train\")\n",
        "    plt.plot([i+1 for i in range(len(val))], val, 'b', label=\"validation\")\n",
        "    plt.xlabel(\"steps\")\n",
        "    plt.ylabel(\"loss\")\n",
        "    plt.legend()\n",
        "    plt.show()\n",
        "    \n",
        "def data_track(data=None,save=True):\n",
        "    if save and len(data) > 0:\n",
        "        with open(\"data.txt\", \"wb\") as file:   #Pickling\n",
        "            pickle.dump(data, file)\n",
        "        torch.cuda.empty_cache()\n",
        "    else:\n",
        "        torch.cuda.empty_cache()\n",
        "        with open(\"data.txt\", \"rb\") as file:   # Unpickling\n",
        "            return pickle.load(file)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "J2MzPDCxRoFu",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "import torch\n",
        "from torch.utils import data\n",
        "import pandas as pd\n",
        "import random\n",
        "import json\n",
        "import numpy as np\n",
        "from skimage import io, transform\n",
        "from PIL import Image\n",
        "\n",
        "class Mds189(data.Dataset):\n",
        "    'Characterizes a dataset for PyTorch'\n",
        "    def __init__(self, label_file, loader, transform):\n",
        "        'Initialization'\n",
        "        self.label_file = label_file\n",
        "        self.loader = loader\n",
        "        self.transform = transform\n",
        "        self.label_map = ['reach','squat','pushup','inline',\n",
        "                          'hamstrings','lunge','deadbug','stretch']\n",
        "        self.data= pd.read_csv(self.label_file,header=None)\n",
        "\n",
        "    def __len__(self):\n",
        "        'Denotes the total number of samples'\n",
        "        return len(self.data)\n",
        "\n",
        "    def map_label_to_int(self,y):\n",
        "        'The labels need to be integers'\n",
        "        label_map = {'reach_both': 0,        # the key frames are labeled with the side\n",
        "                     'squat_both': 1,\n",
        "                     'inline_left': 2,\n",
        "                     'inline_right': 2,\n",
        "                     'lunge_left': 3,\n",
        "                     'lunge_right': 3,\n",
        "                     'hamstrings_left': 4,\n",
        "                     'hamstrings_right': 4,\n",
        "                     'stretch_left': 5,\n",
        "                     'stretch_right': 5,\n",
        "                     'deadbug_left': 6,\n",
        "                     'deadbug_right': 6,\n",
        "                     'pushup_both': 7,\n",
        "                     'reach': 0,            # the video frames don't have information about which side is moving \n",
        "                     'squat': 1,\n",
        "                     'inline': 2,\n",
        "                     'lunge': 3,\n",
        "                     'hamstrings': 4,\n",
        "                     'stretch': 5,\n",
        "                     'deadbug': 6,\n",
        "                     'pushup': 7,\n",
        "                     'label': -1           # label is the placeholder in `videoframe_data_test.txt` for the kaggle frame labels\n",
        "                    }\n",
        "        return label_map[y]\n",
        "\n",
        "    def __getitem__(self,idx):\n",
        "        'Generates one sample of data'\n",
        "        path,target = self.data.iloc[idx]\n",
        "        sample = self.loader(path)\n",
        "        if self.transform is not None:\n",
        "            sample = self.transform(sample)\n",
        "        movement = self.map_label_to_int(target)\n",
        "\n",
        "        return sample,movement"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "I7uxtEXJPuKT",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "import os, sys\n",
        "\n",
        "import torch\n",
        "import torch.nn as nn\n",
        "from torch.utils import data\n",
        "# from mds189 import Mds189\n",
        "import numpy as np\n",
        "from skimage import io, transform\n",
        "import matplotlib.pyplot as plt\n",
        "\n",
        "# import ipdb\n",
        "\n",
        "import torch.nn as nn\n",
        "import torch.nn.functional as F\n",
        "from torchvision import transforms\n",
        "import torchvision.models as models\n",
        "from PIL import Image\n",
        "\n",
        "# from savecsv import preds_to_csv\n",
        "# from model import *\n",
        "\n",
        "# Helper functions for loading images.\n",
        "def pil_loader(path):\n",
        "    # open path as file to avoid ResourceWarning (https://github.com/python-pillow/Pillow/issues/835)\n",
        "    with open(path, 'rb') as f:\n",
        "        img = Image.open(f)\n",
        "        return img.convert('RGB')\n",
        "\n",
        "def accimage_loader(path):\n",
        "    import accimage\n",
        "    try:\n",
        "        return accimage.Image(path)\n",
        "    except IOError:\n",
        "        # Potentially a decoding problem, fall back to PIL.Image\n",
        "        return pil_loader(path)\n",
        "\n",
        "def default_loader(path):\n",
        "    from torchvision import get_image_backend\n",
        "    if get_image_backend() == 'accimage':\n",
        "        return accimage_loader(path)\n",
        "    else:\n",
        "        return pil_loader(path)\n",
        "\n",
        "# CUDA for PyTorch\n",
        "use_cuda = torch.cuda.is_available()\n",
        "device = torch.device(\"cuda:0\" if use_cuda else \"cpu\")\n",
        "#cudnn.benchmark = True\n"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "Fzw5qBd-OAqB",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "import numpy as np\n",
        "\n",
        "def load_preprocess_data(is_train, is_key_frame, params):\n",
        "    \n",
        "    label_file_train, label_file_val, label_file_test = None, None, None\n",
        "    test_dataset, test_loader = None, None\n",
        "    \n",
        "    if is_key_frame:\n",
        "        label_file_train =  'dataloader_files/keyframe_data_train.txt'\n",
        "        label_file_val  =  'dataloader_files/keyframe_data_val.txt'\n",
        "        # NOTE: the kaggle competition test data is only for the video frames, not the key frames\n",
        "        # this is why we don't have an equivalent label_file_test with keyframes\n",
        "    else:\n",
        "        label_file_train = 'dataloader_files/videoframe_data_train.txt'\n",
        "        label_file_val = 'dataloader_files/videoframe_data_val.txt'\n",
        "        label_file_test = 'dataloader_files/videoframe_data_test.txt'\n",
        "        \n",
        "    mean_keytrain = [134.010302198,118.599587912,102.038804945]\n",
        "    std_keytrain = [23.5033438916,23.8827343458,24.5498666589]\n",
        "    mean_randtrain = [133.714058398,118.396875912,102.262895484]\n",
        "    std_randtrain = [23.2021839891,23.7064439547,24.3690056102]\n",
        "    train_dataset = Mds189(label_file_train,loader=default_loader,\\\n",
        "                           transform=transforms.Compose([\n",
        "                               transforms.ColorJitter(hue=.05, saturation=.05),\n",
        "                               transforms.RandomHorizontalFlip(p=0.33),\n",
        "                               transforms.RandomRotation(degrees=15),      \n",
        "                               transforms.ToTensor(),\n",
        "                               transforms.Normalize(mean_keytrain, std_keytrain)\n",
        "                           ]))\n",
        "    train_loader = data.DataLoader(train_dataset, **params)\n",
        "\n",
        "    val_dataset = Mds189(label_file_val,loader=default_loader,\\\n",
        "                         transform=transforms.Compose([\n",
        "                             transforms.ToTensor(),\n",
        "                             transforms.Normalize(mean_keytrain, std_keytrain)\n",
        "                         ]))\n",
        "    val_loader = data.DataLoader(val_dataset, **params)\n",
        "    \n",
        "    if not is_key_frame:\n",
        "        test_dataset = Mds189(label_file_test,loader=default_loader,\\\n",
        "                              transform=transforms.Compose([\n",
        "                                   transforms.ToTensor(),\n",
        "                                   transforms.Normalize(mean_randtrain, std_randtrain)\n",
        "                               ]))\n",
        "        test_loader = data.DataLoader(test_dataset, **params)\n",
        "    \n",
        "    return train_loader, val_loader, test_loader\n",
        "\n",
        "def modelling(model,is_train,is_key_frame,arch,params,hyperparams):\n",
        "    train_loader, val_loader, test_loader = \\\n",
        "    load_preprocess_data(is_train,is_key_frame,params)\n",
        "    train_losses, val_losses = train_val_model(model, \n",
        "                                               train_loader,\n",
        "                                               val_loader, \n",
        "                                               hyperparams)\n",
        "    return (train_losses, val_losses, arch, params)\n",
        "    \n",
        "def train_val_model(model, train_loader, val_loader, hyperparams):\n",
        "    num_epochs,criterion,optimizer = \\\n",
        "    hyperparams[\"num_epochs\"],\\\n",
        "    hyperparams[\"criterion\"],\\\n",
        "    hyperparams[\"optimizer\"]\n",
        "    \n",
        "    print('Beginning training...')\n",
        "    total_step = len(train_loader)\n",
        "    train_losses, val_losses = [], []\n",
        "    for epoch in range(num_epochs):\n",
        "        for i, (local_batch,local_labels) in enumerate(train_loader):\n",
        "            local_ims, local_labels = local_batch.to(device), local_labels.to(device)\n",
        "            outputs = model.forward(local_ims)\n",
        "            loss = criterion(outputs, local_labels)\n",
        "            optimizer.zero_grad()\n",
        "            loss.backward()\n",
        "            optimizer.step()\n",
        "            train_losses.append(loss.item())\n",
        "            if (i+1) % 4 == 0:\n",
        "                torch.save(model.state_dict(), os.getcwd()+\"/\"+model.arch)\n",
        "                print ('Epoch [{}/{}], Step [{}/{}], Training Loss: {:.4f}'\n",
        "                       .format(epoch+1, num_epochs, i+1, total_step, loss.item()))\n",
        "        for i, (local_batch,local_labels) in enumerate(val_loader):\n",
        "            local_ims, local_labels = local_batch.to(device), local_labels.to(device)\n",
        "            outputs = model.forward(local_ims)\n",
        "            loss = criterion(outputs, local_labels)\n",
        "            val_losses.append(loss.item())\n",
        "        print('finished epoch {}, Training Loss: {:.4f}, Validation Loss: {:.4f}'\n",
        "              .format(epoch+1, train_losses[epoch], val_losses[epoch]))\n",
        "    torch.save(model.state_dict(), os.getcwd()+\"/\"+model.arch)\n",
        "    return (train_losses, val_losses)\n",
        "\n",
        "def get_accuracy(model, loader):\n",
        "    print('Starting accuracy calculation!!!')\n",
        "    with torch.no_grad():\n",
        "      correct = 0\n",
        "      total = 0\n",
        "      predicted_list = []\n",
        "      groundtruth_list = []\n",
        "      for (local_batch,local_labels) in loader:\n",
        "          # Transfer to GPU\n",
        "          local_ims, local_labels = local_batch.to(device),\\\n",
        "          local_labels.to(device)\n",
        "          outputs = model.forward(local_ims)\n",
        "          _, predicted = torch.max(outputs.data, 1)\n",
        "          total += local_labels.size(0)\n",
        "          predicted_list.extend(predicted)\n",
        "          groundtruth_list.extend(local_labels)\n",
        "          correct += (predicted == local_labels).sum().item()\n",
        "    \n",
        "    predicted_list = [p.cpu().numpy().tolist() for p in predicted_list]\n",
        "    groundtruth_list = [p.cpu().numpy().tolist() for p in groundtruth_list]\n",
        "    acc = correct / total\n",
        "    print(\"accuracy\",acc)\n",
        "    return acc,predicted_list,groundtruth_list\n",
        "\n",
        "def move_val_acc(pl,gt):\n",
        "    #use pl and gt to produce your confusion matrices\n",
        "    # view the per-movement accuracy\n",
        "    label_map = ['reach','squat','inline','lunge','hamstrings','stretch','deadbug','pushup']\n",
        "    pairs = []\n",
        "    for id in range(len(label_map)):\n",
        "      num = float(sum([p and g for (p,g) in zip(np.array(pl)==np.array(gt),np.array(gt)==id)])+0.00)\n",
        "      denom = float(sum(np.array(gt)==id)+0.0)\n",
        "      acc = num/denom\n",
        "      move = label_map[id]\n",
        "      pairs.append((acc,move))\n",
        "    return pairs"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "zQkvz6XxQe8d",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "import torch\n",
        "import torch.nn as nn\n",
        "import torch.nn.functional as F\n",
        "\n",
        "class NeuralNet(nn.Module):\n",
        "    def __init__(self, arch):\n",
        "        super(NeuralNet, self).__init__()\n",
        "        self.arch = arch\n",
        "        if self.arch[0:10] == \"pytorch_ex\":\n",
        "          self.conv1 = nn.Conv2d(3,8,11,4)\n",
        "          self.mp1 = nn.MaxPool2d(5, 2)\n",
        "          self.conv2 = nn.Conv2d(8,16,5,1,2)\n",
        "          self.mp2 = nn.MaxPool2d(5, 2)\n",
        "          self.conv3 = nn.Conv2d(16,32,3,1,1)\n",
        "          self.conv4 = nn.Conv2d(32,64,3,1,1)\n",
        "          self.mp3 = nn.MaxPool2d(5, 2)        \n",
        "          self.fc1 = nn.Linear(2816, 2048)\n",
        "          self.fc2 = nn.Linear(2048, 1024)\n",
        "          self.fc3 = nn.Linear(1024,8)\n",
        "          nn.init.xavier_normal_(self.conv1.weight)\n",
        "          nn.init.xavier_normal_(self.conv2.weight)\n",
        "          nn.init.xavier_normal_(self.conv3.weight)\n",
        "          nn.init.xavier_normal_(self.conv4.weight)\n",
        "          nn.init.xavier_normal_(self.fc1.weight)\n",
        "          nn.init.xavier_normal_(self.fc2.weight)\n",
        "          nn.init.xavier_normal_(self.fc3.weight)\n",
        "        elif self.arch[0:11] == \"pytorch_adv\":\n",
        "            self.conv1 = nn.Conv2d(3, 4, 5)\n",
        "            self.conv2 = nn.Conv2d(4, 8, 5)\n",
        "            self.conv3 = nn.Conv2d(8, 16, 5)\n",
        "            self.pool = nn.MaxPool2d(2, 2)\n",
        "            self.drop = nn.Dropout()\n",
        "            self.fc1 = nn.Linear(19968, 4096)\n",
        "            self.fc2 = nn.Linear(4096, 2048)\n",
        "            self.fc3 = nn.Linear(2048, 512)\n",
        "            self.fc4 = nn.Linear(512, 8)\n",
        "            nn.init.xavier_normal_(self.conv1.weight)\n",
        "            nn.init.xavier_normal_(self.conv2.weight)\n",
        "            nn.init.xavier_normal_(self.conv3.weight)\n",
        "            nn.init.xavier_normal_(self.fc1.weight)\n",
        "            nn.init.xavier_normal_(self.fc2.weight)\n",
        "            nn.init.xavier_normal_(self.fc3.weight)\n",
        "        \n",
        "    def forward(self, x):\n",
        "        if self.arch[0:10] == \"pytorch_ex\":\n",
        "          x = F.rrelu(self.mp1(self.conv1(x)))\n",
        "          x = F.rrelu(self.mp2(self.conv2(x)))\n",
        "          x = self.mp3(self.conv4(self.conv3(x)))\n",
        "          x = x.view(int(x.size(0)), -1)\n",
        "          x = F.dropout(F.rrelu(self.fc1(x)))\n",
        "          x = F.rrelu(self.fc2(x))\n",
        "          x = self.fc3(x)\n",
        "        elif self.arch[0:11] == \"pytorch_adv\":\n",
        "            x = self.pool(F.leaky_relu(self.conv1(x)))\n",
        "            x = self.pool(F.leaky_relu(self.conv2(x)))\n",
        "            x = self.pool(F.leaky_relu(self.conv3(x)))\n",
        "            x = x.flatten(1)            \n",
        "            x = self.drop(F.leaky_relu(self.fc1(x)))\n",
        "            x = self.drop(F.leaky_relu(self.fc2(x)))\n",
        "            x = F.leaky_relu(self.fc3(x))\n",
        "            x = self.fc4(x)\n",
        "        return x"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "Td1-ldp4QiDX",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "import pandas as pd\n",
        "import numpy as np\n",
        "import datetime\n",
        "\n",
        "def preds_to_csv(y,header=\"\"):\n",
        "    y = y.astype(int)\n",
        "    df = pd.DataFrame({'Category': y})\n",
        "    df.index += 1  # Ensures that the index starts at 1. \n",
        "    df.to_csv(str(header+\"_\"+str(datetime.datetime.now().time())+'_submission.csv'),index_label='Id')\n",
        "    print(\"saved predictions\")"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "Q387zcMWJ5iO",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "!ls"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Dl8GOKOqiIDN",
        "colab_type": "text"
      },
      "source": [
        "# 4a"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "kJQ-2_RbW8I6",
        "colab_type": "text"
      },
      "source": [
        "## Model 1"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "hxVyxDdwiIDO",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "is_train = True\n",
        "is_key_frame = True\n",
        "arch = \"pytorch_adv_64key\"\n",
        "params = {'batch_size': 64,'shuffle': True,'num_workers': 4}\n",
        "hyperparams = {\"num_epochs\":10,\"criterion\":nn.CrossEntropyLoss()}\n",
        "model = NeuralNet(arch).to(device)\n",
        "hyperparams[\"optimizer\"] = torch.optim.Adam(model.parameters())\n",
        "models_data.append(modelling(model,is_train,is_key_frame,arch,params,hyperparams))\n",
        "data_track(models_data,save=True)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "ksd0NqTMCoIR",
        "colab": {}
      },
      "source": [
        "#TESTING\n",
        "_,val_loader,_ = load_preprocess_data(is_train=False,\n",
        "                                         is_key_frame=True,\n",
        "                                         params=models_data[0][3])\n",
        "key_acc,key_predicted_list,key_groundtruth_list = get_accuracy(model, val_loader)\n",
        "key_pairs = move_val_acc(key_predicted_list, key_groundtruth_list)\n",
        "key_pairs"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "t0cogbZJW_RY",
        "colab_type": "text"
      },
      "source": [
        "## Model 2"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "GNaVokEWiIDV",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "models_data = data_track(save=False)\n",
        "is_train = True\n",
        "is_key_frame = True\n",
        "arch = \"pytorch_ex_64sgd\"\n",
        "params = {'batch_size': 64,'shuffle': True,'num_workers': 4}\n",
        "hyperparams = {\"num_epochs\":10,\"criterion\":nn.CrossEntropyLoss()}\n",
        "model = NeuralNet(arch).to(device)\n",
        "hyperparams[\"optimizer\"] = torch.optim.SGD(model.parameters(), lr=1e-3, momentum=0.9)\n",
        "models_data.append(modelling(model,is_train,is_key_frame,arch,params,hyperparams))\n",
        "data_track(models_data,save=True)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "tSGBUj6fCqBd",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "#TESTING\n",
        "_,val_loader,_ = load_preprocess_data(is_train=False,\n",
        "                                         is_key_frame=True,\n",
        "                                         params=models_data[-1][3])\n",
        "key_acc,key_predicted_list,key_groundtruth_list = get_accuracy(model, val_loader)\n",
        "key_pairs = move_val_acc(key_predicted_list, key_groundtruth_list)\n",
        "key_pairs"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "qUehOwqBWr-G",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "[m[2] for m in models_data]"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "iMg8uigJXE02",
        "colab_type": "text"
      },
      "source": [
        "## Model 3"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "AUFDdG1WiIDa",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "models_data = data_track(save=False)\n",
        "is_train = True\n",
        "is_key_frame = True\n",
        "arch = \"pytorch_ex_128adam\"\n",
        "params = {'batch_size': 128,'shuffle': True,'num_workers': 4}\n",
        "hyperparams = {\"num_epochs\":15,\"criterion\":nn.CrossEntropyLoss()}\n",
        "model = NeuralNet(arch).to(device)\n",
        "hyperparams[\"optimizer\"] = torch.optim.Adam(model.parameters())\n",
        "models_data.append(modelling(model,is_train,is_key_frame,arch,params,hyperparams))\n",
        "data_track(models_data,save=True)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "N8dfoAdSkeKt",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "#TESTING\n",
        "_,val_loader,_ = load_preprocess_data(is_train=False,\n",
        "                                         is_key_frame=True,\n",
        "                                         params=models_data[-1][3])\n",
        "key_acc,key_predicted_list,key_groundtruth_list = get_accuracy(model, val_loader)\n",
        "key_pairs = move_val_acc(key_predicted_list, key_groundtruth_list)\n",
        "key_pairs"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "fif6GJvXWtDd",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "[m[2] for m in models_data]"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "vTgDUCyniIDh",
        "colab_type": "text"
      },
      "source": [
        "# 4b"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "74Ov7FFbiIDi",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "for i in range(len(models_data)):\n",
        "    plot_loss(models_data[i][2],models_data[i][0],models_data[i][1])"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Ap4zZNDjiIDo",
        "colab_type": "text"
      },
      "source": [
        "# 4c"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "p87Sl9ghiIDp",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "[m[2] for m in models_data]"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "7k0JPWY0iIDv",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "sum_model = NeuralNet(models_data[1][2]).to(device)\n",
        "sum_model.load_state_dict(torch.load(os.getcwd()+\"/\"+models_data[1][2]))\n",
        "sum_model.eval()\n",
        "print(sum_model)\n",
        "print(summary(sum_model, input_size=(3, 224, 448)))"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "-dmeG66JiID1",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "l1=(6*220*444)\n",
        "l2=(6*110*222)\n",
        "l3=(16*106*218)\n",
        "l4=(16*53*109)\n",
        "l5=512\n",
        "l6=128\n",
        "l7=9\n",
        "num=(l1*l2)+(l2*l3)+(l3*l4)+(l4*l5)+(l5*l6)+(l6*l7)\n",
        "print(\"number of parameters in comparable fully-connected layers NN:\"\n",
        "      ,num)\n"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "fSjLUyvNiID6",
        "colab_type": "text"
      },
      "source": [
        "# 4d"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "Sq0RC2ISFXKs",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "models_data = data_track(save=False)\n",
        "is_train = True\n",
        "is_key_frame = False\n",
        "arch = \"pytorch_ex_64sgd_random\"\n",
        "params = {'batch_size': 64,'shuffle': True,'num_workers': 4}\n",
        "hyperparams = {\"num_epochs\": 2,\"criterion\":nn.CrossEntropyLoss()}\n",
        "model = NeuralNet(arch).to(device)\n",
        "hyperparams[\"optimizer\"] = torch.optim.SGD(model.parameters(), lr=1e-3, momentum=0.9)\n",
        "mod_data = modelling(model,is_train,is_key_frame,arch,params,hyperparams)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "aARoGDrGiIEB",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "models_data.append(mod_data)\n",
        "data_track(models_data,save=True)\n",
        "plot_loss(models_data[3][2],models_data[3][0],models_data[3][1])"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "dyEoQNFxiIEH",
        "colab_type": "text"
      },
      "source": [
        "# 4e"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "BxFfBoedM2VF",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "models_data = data_track(save=False)\n",
        "[m[2] for m in models_data]"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "T2gWS5oWufkD",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "key_model = NeuralNet(models_data[1][2]).to(device)\n",
        "key_model.load_state_dict(torch.load(os.getcwd()+\"/\"+models_data[1][2]))\n",
        "key_model.eval()\n",
        "_,keyval_loader,_ = load_preprocess_data(is_train=False,\n",
        "                                         is_key_frame=True,\n",
        "                                         params=models_data[1][3])\n",
        "rand_model = NeuralNet(models_data[3][2]).to(device)\n",
        "rand_model.load_state_dict(torch.load(os.getcwd()+\"/\"+models_data[3][2]))\n",
        "rand_model.eval()\n",
        "_,randval_loader,_ = load_preprocess_data(is_train=False,\n",
        "                                          is_key_frame=False,\n",
        "                                          params=models_data[3][3])"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "eHpKJJKciIES",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "key_acc,key_predicted_list,key_groundtruth_list = get_accuracy(key_model, keyval_loader)\n",
        "rand_acc,rand_predicted_list,rand_groundtruth_list = get_accuracy(rand_model, randval_loader)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "6YF2jHg_WKa9",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "key_pairs = move_val_acc(key_predicted_list, key_groundtruth_list)\n",
        "rand_pairs = move_val_acc(rand_predicted_list, rand_groundtruth_list)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "eOljKe3UiIEX",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "accs = [[\"key frame\"]+[p[0] for p in key_pairs]+[key_acc],[\"random frame\"]+[p[0] for p in rand_pairs]+[rand_acc]]\n",
        "cols = [\"frame type\",'reach','squat','inline','lunge','hamstrings','stretch','deadbug','pushup',\"overall\"]\n",
        "df = pd.DataFrame(accs,columns=cols)\n",
        "print(\"accuracies\")\n",
        "df"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "I2dqVJ6iiIEb",
        "colab_type": "text"
      },
      "source": [
        "# 4f"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "7btA7EgwiIEc",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "cm = confusion_matrix(key_groundtruth_list, \n",
        "                 key_predicted_list)\n",
        "cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]\n",
        "fig, ax = plt.subplots()\n",
        "classes = ['reach','squat','inline','lunge','hamstrings','stretch','deadbug','pushup']\n",
        "im = ax.imshow(cm, interpolation='nearest', cmap=plt.cm.Blues)\n",
        "ax.figure.colorbar(im, ax=ax)\n",
        "ax.set(xticks=np.arange(cm.shape[1]),\n",
        "       yticks=np.arange(cm.shape[0]),\n",
        "       xticklabels=classes, yticklabels=classes,\n",
        "       title=\"confusion matrix for key frame model\",\n",
        "       ylabel='True label',\n",
        "       xlabel='Predicted label');\n",
        "plt.xticks(rotation=90);"
      ],
      "execution_count": 0,
      "outputs": []
    }
  ]
}